package com.ppm.project.manuscripts.service.impl;

import java.util.*;

import com.ppm.common.constant.Constants;
import com.ppm.common.constant.ErrorConstants;
import com.ppm.common.exception.user.SiteCodeUniqueCheckException;
import com.ppm.common.utils.StringUtils;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ppm.common.exception.CustomException;
import com.ppm.framework.redis.RedisCache;
import com.ppm.project.manuscripts.domain.PpmSiteSource;
import com.ppm.project.manuscripts.mapper.PpmSiteSourceMapper;
import com.ppm.project.manuscripts.service.IPpmSiteSourceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

/**
 * 来源站点Service业务层处理
 *
 * @author ppm
 * @date 2020-04-02
 */
@Service
public class PpmSiteSourceServiceImpl extends ServiceImpl<PpmSiteSourceMapper,PpmSiteSource> implements IPpmSiteSourceService
{
    private static final Logger log = LoggerFactory.getLogger(PpmSiteSourceServiceImpl.class);

    @Autowired
    private PpmSiteSourceMapper ppmSiteSourceMapper;

    @Autowired

    private RedisCache redisCache;


    /**
     * 查询来源站点
     *
     * @param siteSourceId 来源站点ID
     * @return 来源站点
     */
    @Override
    public PpmSiteSource selectPpmSiteSourceById(Long siteSourceId)
    {
        return ppmSiteSourceMapper.selectPpmSiteSourceById(siteSourceId);
    }

    /**
     * 查询来源站点列表
     *
     * @param ppmSiteSource 来源站点
     * @return 来源站点
     */
    @Override
    public List<PpmSiteSource> selectPpmSiteSourceList(PpmSiteSource ppmSiteSource)
    {
        return ppmSiteSourceMapper.selectPpmSiteSourceList(ppmSiteSource);
    }

    /**
     * 新增来源站点
     *
     * @param ppmSiteSource 来源站点
     * @return 结果
     */
    @Override
    public int insertPpmSiteSource(PpmSiteSource ppmSiteSource)
    {
        int result = 0;
        try {
            //删除缓存
            redisCache.deleteObject(Constants.SITE_SOURCE_KEY);
            result = ppmSiteSourceMapper.insertPpmSiteSource(ppmSiteSource);
        }catch (Throwable e){
            if(e instanceof DuplicateKeyException && e.getCause()!=null
                    && StringUtils.isNotEmpty(e.getCause().getMessage())
                    && e.getCause().getMessage().contains("site_code_uq")){
                throw new SiteCodeUniqueCheckException(ErrorConstants.DB_UNIQUEKEY_CHECK_ERROR,
                        "操作失败,源编码"+ppmSiteSource.getSiteCode()+"已存在",e);
            }else{
                throw new CustomException(e.getMessage(),e);
            }
        }
        return result;

    }

    /**
     * 修改来源站点
     *
     * @param ppmSiteSource 来源站点
     * @return 结果
     */
    @Override
    public int updatePpmSiteSource(PpmSiteSource ppmSiteSource)
    {
        int result = 0;
        try {
            //删除缓存
            redisCache.deleteObject(Constants.SITE_SOURCE_KEY);
            result = ppmSiteSourceMapper.updatePpmSiteSource(ppmSiteSource);
        }catch (Throwable e){
            if(e instanceof DuplicateKeyException && e.getCause()!=null
                    && StringUtils.isNotEmpty(e.getCause().getMessage())
                    && e.getCause().getMessage().contains("site_code_uq")){
                throw new SiteCodeUniqueCheckException(ErrorConstants.DB_UNIQUEKEY_CHECK_ERROR,
                        "操作失败,源编码"+ppmSiteSource.getSiteCode()+"已存在",e);
            }else{
                throw new CustomException(e.getMessage(),e);
            }
        }
        return result;
    }

    /**
     * 批量删除来源站点
     *
     * @param siteSourceIds 需要删除的来源站点ID
     * @return 结果
     */
    @Override
    public int deletePpmSiteSourceByIds(Long[] siteSourceIds)
    {
        //删除缓存
        redisCache.deleteObject(Constants.SITE_SOURCE_KEY);
        return ppmSiteSourceMapper.deletePpmSiteSourceByIds(siteSourceIds);
    }

    /**
     * 删除来源站点信息
     *
     * @param siteSourceId 来源站点ID
     * @return 结果
     */
    @Override
    public int deletePpmSiteSourceById(Long siteSourceId)
    {
        //删除缓存
        redisCache.deleteObject(Constants.SITE_SOURCE_KEY);
        return ppmSiteSourceMapper.deletePpmSiteSourceById(siteSourceId);
    }

    @Override
    public Map<String, List<String>> getAllSite() {
        Map<String, List<String>> allSiteMap = redisCache.getCacheObject(Constants.SITE_SOURCE_KEY);

        if(allSiteMap == null || allSiteMap.size()< 1){

            synchronized (PpmSiteSourceServiceImpl.class){
                if (allSiteMap == null || allSiteMap.size()< 1){
                    //从数据库获取
                    allSiteMap = getAllSiteFromDB();
                    redisCache.setCacheObject(Constants.SITE_SOURCE_KEY, allSiteMap);
                }
            }
        }
        return allSiteMap;
    }

    private Map<String, List<String>> getAllSiteFromDB(){

        List<PpmSiteSource> rootSiteSourceList = list(new QueryWrapper<PpmSiteSource>()
                .eq("parent_site_code" , "0").orderByAsc("site_code"));
        List<PpmSiteSource> nrootSiteSourceList = list(new QueryWrapper<PpmSiteSource>()
                .ne("parent_site_code" , "0").orderByAsc("site_code"));
        Map<String,List<String>> siteJsonMap = new LinkedHashMap<>();
        List<PpmSiteSource> linkNrootSiteSourceList = new LinkedList<>(nrootSiteSourceList);
        //需清除的集合
        List<PpmSiteSource> removeRootSiteSourceList = new LinkedList<>();
        for(PpmSiteSource rootPpmSiteSource :rootSiteSourceList){
            List<String> cityList = new ArrayList<>();
            siteJsonMap.put(rootPpmSiteSource.getSiteCode()+"-"+rootPpmSiteSource.getSiteName(), cityList);
            cityList.add(rootPpmSiteSource.getSiteCode()+"-全部区县");
            //迭代器遍历linkedList
            Iterator<PpmSiteSource> iterator = linkNrootSiteSourceList.iterator();
            while (iterator.hasNext()){
                PpmSiteSource nrootSiteSource = iterator.next();
                if(rootPpmSiteSource.getSiteCode().equals(nrootSiteSource.getParentSiteCode())){
                    cityList.add(nrootSiteSource.getSiteCode()+"-"+nrootSiteSource.getSiteName());
                    removeRootSiteSourceList.add(nrootSiteSource);
                }
            }
            //已组装的数据清除，避免重复遍历
            linkNrootSiteSourceList.removeAll(removeRootSiteSourceList);
            removeRootSiteSourceList.clear();
        }
        return siteJsonMap;

    }

    @Override
    public String importSiteSource(List<PpmSiteSource> siteList, Boolean isUpdateSupport, String operName) {
        if (StringUtils.isNull(siteList) || siteList.size() == 0)
        {
            throw new CustomException("导入来源站点数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (PpmSiteSource siteSource : siteList)
        {
            try
            {
                // 验证是否存在
                PpmSiteSource p = ppmSiteSourceMapper.selectOne(new QueryWrapper<PpmSiteSource>()
                        .eq("site_code", siteSource.getSiteCode()));
                if (StringUtils.isNull(p))
                {
                    siteSource.setCreateBy(operName);
                    this.insertPpmSiteSource(siteSource);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、站点 ["+siteSource.getSiteCode()+"]" + siteSource.getSiteName() + " 导入成功");
                }
                else if (isUpdateSupport)
                {
                    siteSource.setUpdateBy(operName);
                    siteSource.setId(p.getId());
                    this.updatePpmSiteSource(siteSource);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、站点 ["+siteSource.getSiteCode()+"]" + siteSource.getSiteName() + " 更新成功");
                }
                else
                {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、站点 ["+siteSource.getSiteCode()+"]" + siteSource.getSiteName() + " 已存在");
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>" + failureNum + "、站点 ["+siteSource.getSiteCode()+"]" + siteSource.getSiteName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new CustomException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }
}
